{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "bb04f1a2-1f87-42e6-a5ad-453eec40215f",
   "metadata": {},
   "source": [
    "# Models API\n",
    "\n",
    "使用 Models API 查看和访问 OpenAI 提供的预训练大语言模型"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7466990e-c2ac-441c-a545-fdc122e752ca",
   "metadata": {},
   "source": [
    "## List Models\n",
    "\n",
    "列出当前可用的模型，并提供每个模型的基本信息，如所有者和可用性。"
   ]
  },
  {
   "cell_type": "code",
   "id": "f453ab0c-b262-4fa5-993e-b4b341e46a94",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-13T03:20:11.335142Z",
     "start_time": "2024-05-13T03:20:10.300907Z"
    }
   },
   "source": [
    "import os\n",
    "from openai import OpenAI\n",
    "client = OpenAI(base_url='https://bd-gateway-agent.sdpsg.101.com/openai/v1/', api_key=os.getenv('OPENAI_API_KEY'))    # 使用网龙自己的URL\n",
    "\n",
    "models = client.models.list()"
   ],
   "outputs": [
    {
     "ename": "NotFoundError",
     "evalue": "Error code: 404 - {'host_id': 'bd-gateway-agent.sdpsg.101.com', 'request_id': 'bd-gateway-agent-10.129.131.92^1715266258456^26888', 'server_time': '2024-05-13T11:20:11.273+08:00', 'code': 'WAF/URI_NOT_FOUND', 'message': '由于网络等原因，您当前的访问受阻。如果需要，请联系相关管理员。', 'force_update': None, 'detail': 'Message:No handler found for GET /openai/v1/models \\r\\n SourceAppName:bd-gateway-agent \\r\\n ', 'cause': None}",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mNotFoundError\u001B[0m                             Traceback (most recent call last)",
      "Cell \u001B[1;32mIn[4], line 5\u001B[0m\n\u001B[0;32m      2\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mopenai\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m OpenAI\n\u001B[0;32m      3\u001B[0m client \u001B[38;5;241m=\u001B[39m OpenAI(base_url\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mhttps://bd-gateway-agent.sdpsg.101.com/openai/v1/\u001B[39m\u001B[38;5;124m'\u001B[39m, api_key\u001B[38;5;241m=\u001B[39mos\u001B[38;5;241m.\u001B[39mgetenv(\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mOPENAI_API_KEY\u001B[39m\u001B[38;5;124m'\u001B[39m))    \u001B[38;5;66;03m# 使用网龙自己的URL\u001B[39;00m\n\u001B[1;32m----> 5\u001B[0m models \u001B[38;5;241m=\u001B[39m \u001B[43mclient\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mmodels\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mlist\u001B[49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\n",
      "File \u001B[1;32mD:\\ProgramFiles\\Miniconda\\envs\\AllInOne\\lib\\site-packages\\openai\\resources\\models.py:79\u001B[0m, in \u001B[0;36mModels.list\u001B[1;34m(self, extra_headers, extra_query, extra_body, timeout)\u001B[0m\n\u001B[0;32m     65\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mlist\u001B[39m(\n\u001B[0;32m     66\u001B[0m     \u001B[38;5;28mself\u001B[39m,\n\u001B[0;32m     67\u001B[0m     \u001B[38;5;241m*\u001B[39m,\n\u001B[1;32m   (...)\u001B[0m\n\u001B[0;32m     73\u001B[0m     timeout: \u001B[38;5;28mfloat\u001B[39m \u001B[38;5;241m|\u001B[39m httpx\u001B[38;5;241m.\u001B[39mTimeout \u001B[38;5;241m|\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m \u001B[38;5;241m|\u001B[39m NotGiven \u001B[38;5;241m=\u001B[39m NOT_GIVEN,\n\u001B[0;32m     74\u001B[0m ) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m SyncPage[Model]:\n\u001B[0;32m     75\u001B[0m \u001B[38;5;250m    \u001B[39m\u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[0;32m     76\u001B[0m \u001B[38;5;124;03m    Lists the currently available models, and provides basic information about each\u001B[39;00m\n\u001B[0;32m     77\u001B[0m \u001B[38;5;124;03m    one such as the owner and availability.\u001B[39;00m\n\u001B[0;32m     78\u001B[0m \u001B[38;5;124;03m    \"\"\"\u001B[39;00m\n\u001B[1;32m---> 79\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_get_api_list\u001B[49m\u001B[43m(\u001B[49m\n\u001B[0;32m     80\u001B[0m \u001B[43m        \u001B[49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43m/models\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m,\u001B[49m\n\u001B[0;32m     81\u001B[0m \u001B[43m        \u001B[49m\u001B[43mpage\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mSyncPage\u001B[49m\u001B[43m[\u001B[49m\u001B[43mModel\u001B[49m\u001B[43m]\u001B[49m\u001B[43m,\u001B[49m\n\u001B[0;32m     82\u001B[0m \u001B[43m        \u001B[49m\u001B[43moptions\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mmake_request_options\u001B[49m\u001B[43m(\u001B[49m\n\u001B[0;32m     83\u001B[0m \u001B[43m            \u001B[49m\u001B[43mextra_headers\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mextra_headers\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mextra_query\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mextra_query\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mextra_body\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mextra_body\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mtimeout\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mtimeout\u001B[49m\n\u001B[0;32m     84\u001B[0m \u001B[43m        \u001B[49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\n\u001B[0;32m     85\u001B[0m \u001B[43m        \u001B[49m\u001B[43mmodel\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mModel\u001B[49m\u001B[43m,\u001B[49m\n\u001B[0;32m     86\u001B[0m \u001B[43m    \u001B[49m\u001B[43m)\u001B[49m\n",
      "File \u001B[1;32mD:\\ProgramFiles\\Miniconda\\envs\\AllInOne\\lib\\site-packages\\openai\\_base_client.py:1282\u001B[0m, in \u001B[0;36mSyncAPIClient.get_api_list\u001B[1;34m(self, path, model, page, body, options, method)\u001B[0m\n\u001B[0;32m   1271\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mget_api_list\u001B[39m(\n\u001B[0;32m   1272\u001B[0m     \u001B[38;5;28mself\u001B[39m,\n\u001B[0;32m   1273\u001B[0m     path: \u001B[38;5;28mstr\u001B[39m,\n\u001B[1;32m   (...)\u001B[0m\n\u001B[0;32m   1279\u001B[0m     method: \u001B[38;5;28mstr\u001B[39m \u001B[38;5;241m=\u001B[39m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mget\u001B[39m\u001B[38;5;124m\"\u001B[39m,\n\u001B[0;32m   1280\u001B[0m ) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m SyncPageT:\n\u001B[0;32m   1281\u001B[0m     opts \u001B[38;5;241m=\u001B[39m FinalRequestOptions\u001B[38;5;241m.\u001B[39mconstruct(method\u001B[38;5;241m=\u001B[39mmethod, url\u001B[38;5;241m=\u001B[39mpath, json_data\u001B[38;5;241m=\u001B[39mbody, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39moptions)\n\u001B[1;32m-> 1282\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_request_api_list\u001B[49m\u001B[43m(\u001B[49m\u001B[43mmodel\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mpage\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mopts\u001B[49m\u001B[43m)\u001B[49m\n",
      "File \u001B[1;32mD:\\ProgramFiles\\Miniconda\\envs\\AllInOne\\lib\\site-packages\\openai\\_base_client.py:1127\u001B[0m, in \u001B[0;36mSyncAPIClient._request_api_list\u001B[1;34m(self, model, page, options)\u001B[0m\n\u001B[0;32m   1123\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m resp\n\u001B[0;32m   1125\u001B[0m options\u001B[38;5;241m.\u001B[39mpost_parser \u001B[38;5;241m=\u001B[39m _parser\n\u001B[1;32m-> 1127\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mrequest\u001B[49m\u001B[43m(\u001B[49m\u001B[43mpage\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43moptions\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mstream\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;28;43;01mFalse\u001B[39;49;00m\u001B[43m)\u001B[49m\n",
      "File \u001B[1;32mD:\\ProgramFiles\\Miniconda\\envs\\AllInOne\\lib\\site-packages\\openai\\_base_client.py:922\u001B[0m, in \u001B[0;36mSyncAPIClient.request\u001B[1;34m(self, cast_to, options, remaining_retries, stream, stream_cls)\u001B[0m\n\u001B[0;32m    913\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mrequest\u001B[39m(\n\u001B[0;32m    914\u001B[0m     \u001B[38;5;28mself\u001B[39m,\n\u001B[0;32m    915\u001B[0m     cast_to: Type[ResponseT],\n\u001B[1;32m   (...)\u001B[0m\n\u001B[0;32m    920\u001B[0m     stream_cls: \u001B[38;5;28mtype\u001B[39m[_StreamT] \u001B[38;5;241m|\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m,\n\u001B[0;32m    921\u001B[0m ) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m ResponseT \u001B[38;5;241m|\u001B[39m _StreamT:\n\u001B[1;32m--> 922\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_request\u001B[49m\u001B[43m(\u001B[49m\n\u001B[0;32m    923\u001B[0m \u001B[43m        \u001B[49m\u001B[43mcast_to\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mcast_to\u001B[49m\u001B[43m,\u001B[49m\n\u001B[0;32m    924\u001B[0m \u001B[43m        \u001B[49m\u001B[43moptions\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43moptions\u001B[49m\u001B[43m,\u001B[49m\n\u001B[0;32m    925\u001B[0m \u001B[43m        \u001B[49m\u001B[43mstream\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mstream\u001B[49m\u001B[43m,\u001B[49m\n\u001B[0;32m    926\u001B[0m \u001B[43m        \u001B[49m\u001B[43mstream_cls\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mstream_cls\u001B[49m\u001B[43m,\u001B[49m\n\u001B[0;32m    927\u001B[0m \u001B[43m        \u001B[49m\u001B[43mremaining_retries\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mremaining_retries\u001B[49m\u001B[43m,\u001B[49m\n\u001B[0;32m    928\u001B[0m \u001B[43m    \u001B[49m\u001B[43m)\u001B[49m\n",
      "File \u001B[1;32mD:\\ProgramFiles\\Miniconda\\envs\\AllInOne\\lib\\site-packages\\openai\\_base_client.py:1013\u001B[0m, in \u001B[0;36mSyncAPIClient._request\u001B[1;34m(self, cast_to, options, remaining_retries, stream, stream_cls)\u001B[0m\n\u001B[0;32m   1010\u001B[0m         err\u001B[38;5;241m.\u001B[39mresponse\u001B[38;5;241m.\u001B[39mread()\n\u001B[0;32m   1012\u001B[0m     log\u001B[38;5;241m.\u001B[39mdebug(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mRe-raising status error\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n\u001B[1;32m-> 1013\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_make_status_error_from_response(err\u001B[38;5;241m.\u001B[39mresponse) \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m\n\u001B[0;32m   1015\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_process_response(\n\u001B[0;32m   1016\u001B[0m     cast_to\u001B[38;5;241m=\u001B[39mcast_to,\n\u001B[0;32m   1017\u001B[0m     options\u001B[38;5;241m=\u001B[39moptions,\n\u001B[1;32m   (...)\u001B[0m\n\u001B[0;32m   1020\u001B[0m     stream_cls\u001B[38;5;241m=\u001B[39mstream_cls,\n\u001B[0;32m   1021\u001B[0m )\n",
      "\u001B[1;31mNotFoundError\u001B[0m: Error code: 404 - {'host_id': 'bd-gateway-agent.sdpsg.101.com', 'request_id': 'bd-gateway-agent-10.129.131.92^1715266258456^26888', 'server_time': '2024-05-13T11:20:11.273+08:00', 'code': 'WAF/URI_NOT_FOUND', 'message': '由于网络等原因，您当前的访问受阻。如果需要，请联系相关管理员。', 'force_update': None, 'detail': 'Message:No handler found for GET /openai/v1/models \\r\\n SourceAppName:bd-gateway-agent \\r\\n ', 'cause': None}"
     ]
    }
   ],
   "execution_count": 4
  },
  {
   "cell_type": "code",
   "id": "87dbc132-41cd-4ebc-928f-9edf6a4befcd",
   "metadata": {},
   "source": [
    "print(models)"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "id": "6b69d74e-a79d-4832-9bda-2a5b9df7e68d",
   "metadata": {},
   "source": [
    "#### 查看 OpenAI 最新提供的模型 API 信息\n",
    "\n",
    "`models.data`: 目前OpenAI提供的大语言模型列表，列表中的每一项都对应着一个模型实例。\n",
    "\n",
    "以`GPT-3.5-Turbo`模型为例，解释说明各项参数：\n",
    "\n",
    "1. `created`: 这是模型创建的时间戳，单位为 Unix 时间戳（自1970年1月1日（00:00:00 GMT）以后的秒数）。\n",
    "2. `id`: 这是模型的唯一标识符。在这个例子中，模型的 ID 是 \"text-davinci-003\"。\n",
    "3. `object`: 这个字段表示的是当前对象的类型，在这个例子中，对象是 \"model\"，说明这个 JSON 对象是一个模型。\n",
    "4. `owned_by`: 这个字段表示的是模型的所有者，在这个例子中，模型的所有者是 \"openai-internal\"。"
   ]
  },
  {
   "cell_type": "code",
   "id": "82922dd9-f38e-4ec1-8be0-361aefb99d7b",
   "metadata": {},
   "source": [
    "models.data"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "id": "774e3a12-01f6-44ad-8829-03510f5d9df6",
   "metadata": {},
   "source": [
    "### 获取模型 ID 列表"
   ]
  },
  {
   "cell_type": "code",
   "id": "dd351597-b055-4d30-aa0b-b5e468f7b924",
   "metadata": {},
   "source": [
    "models.data[0].id"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "fdb8752e-bcb8-4732-a037-1835861c20a7",
   "metadata": {},
   "source": [
    "model_list = [model.id for model in models.data]"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "3372f33d-4302-4fc6-9eac-e1d34cf216be",
   "metadata": {},
   "source": [
    "print(model_list)"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "id": "75d2a270-949c-4ad2-a568-e254e6231333",
   "metadata": {},
   "source": [
    "## Retrieve Model\n",
    "\n",
    "根据前面查询到当前支持的模型ID列表，获取指定模型实例，如`gpt-3.5-turbo`。"
   ]
  },
  {
   "cell_type": "code",
   "id": "6fd7eca9-ed5a-4bca-8f9c-a0bf36177d31",
   "metadata": {},
   "source": [
    "from openai import OpenAI\n",
    "client = OpenAI(base_url='https://bd-gateway-agent.sdpsg.101.com/openai/v1/', api_key=os.getenv('OPENAI_API_KEY'))    # 使用网龙自己的URL\n",
    "\n",
    "# 将模型 ID 传入 retrieve 接口\n",
    "gpt_3 = client.models.retrieve(\"gpt-3.5-turbo\")"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "51078b58-67db-467a-b09f-ef40562f1fad",
   "metadata": {},
   "source": [
    "print(gpt_3)"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "id": "67bd0916-d771-4745-85bb-28be33806d89",
   "metadata": {},
   "source": [
    "### 获取指定模型，如 GPT-4V"
   ]
  },
  {
   "cell_type": "code",
   "id": "2ea16de8-add9-4ad4-b5b9-ebb959d7ab7f",
   "metadata": {},
   "source": [
    "client.models.retrieve(\"gpt-4-vision-preview\")"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "fa107114-28cd-435a-a4b0-c9ceabddf415",
   "metadata": {},
   "source": [],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "id": "028f4f7e-3be1-44d7-bfcd-c65a13e85093",
   "metadata": {},
   "source": [
    "# 文本内容补全初探（Completions API）[Legacy]\n",
    "\n",
    "使用 Completions API 实现各类文本生成任务\n",
    "\n",
    "\n",
    "主要请求参数说明：\n",
    "\n",
    "\n",
    "- **`model`** （string，必填）\n",
    "\n",
    "  要使用的模型的 ID。可以参考 **模型端点兼容性表**。\n",
    "\n",
    "- **`prompt`** （string or array，必填，Defaults to ）\n",
    "\n",
    "  生成补全的提示，编码为字符串、字符串数组、token数组或token数组数组。\n",
    "\n",
    "  注意，这是模型在训练过程中看到的文档分隔符，所以如果没有指定提示符，模型将像从新文档的开头一样生成。\n",
    "\n",
    "- **`stream`** （boolean，选填，默认 false）\n",
    "\n",
    "  当它设置为 true 时，API 会以 SSE（ Server Side Event ）方式返回内容，即会不断地输出内容直到完成响应，流通过 `data: [DONE]` 消息终止。\n",
    "\n",
    "- **`max_tokens`** （integer，选填，默认是 16）\n",
    "\n",
    "  补全时要生成的最大 token 数。\n",
    "\n",
    "  提示 `max_tokens` 的 token 计数不能超过模型的上下文长度。大多数模型的上下文长度为 2048 个token（最新模型除外，它支持 4096）\n",
    "\n",
    "- **`temperature`** （number，选填，默认是1）\n",
    "\n",
    "  使用哪个采样温度，在 **0和2之间**。\n",
    "\n",
    "  较高的值，如0.8会使输出更随机，而较低的值，如0.2会使其更加集中和确定性。\n",
    "\n",
    "  通常建议修改这个（`temperature` ）或 `top_p` 但两者不能同时存在，二选一。\n",
    "\n",
    "- **`n`** （integer，选填，默认为 1）\n",
    "\n",
    "  每个 `prompt` 生成的补全次数。\n",
    "\n",
    "  注意：由于此参数会生成许多补全，因此它会快速消耗token配额。小心使用，并确保对 `max_tokens` 和 `stop` 进行合理的设置。\n",
    "\n",
    "\n",
    "## 生成英文文本"
   ]
  },
  {
   "cell_type": "code",
   "id": "0526acb1-5741-48b6-ae64-917ad0d064b4",
   "metadata": {},
   "source": [
    "import os\n",
    "from openai import OpenAI\n",
    "\n",
    "client = OpenAI(base_url='https://bd-gateway-agent.sdpsg.101.com/openai/v1/', api_key=os.getenv('OPENAI_API_KEY'))    # 使用网龙自己的URL\n",
    "\n",
    "data = client.completions.create(\n",
    "  model=\"gpt-3.5-turbo-instruct\",\n",
    "  prompt=\"Say this is a test\",\n",
    "  max_tokens=7,\n",
    "  temperature=0\n",
    ")"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "af7a8d1f-c2f7-421d-bd0d-0890d06a0c34",
   "metadata": {},
   "source": [
    "print(data)"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "63cddd0f-a8f3-4f62-891a-8146306a5d95",
   "metadata": {},
   "source": [
    "text = data.choices[0].text"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "49cbd498-bfa5-4d11-a6ee-30822b24dcc8",
   "metadata": {},
   "source": [
    "print(text)"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "c43d83bd-375f-4256-925a-e894d0e155a0",
   "metadata": {},
   "source": [],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "159f1bf9-1604-414c-af74-45b22c33a7f9",
   "metadata": {},
   "source": [],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "id": "5c79be11-b2b4-4580-ad10-b7111cb950ea",
   "metadata": {},
   "source": [
    "## 生成中文文本\n",
    "\n",
    "调整 `max_tokens` "
   ]
  },
  {
   "cell_type": "code",
   "id": "3e3a4018-7c72-49a1-942b-167c3941fb96",
   "metadata": {},
   "source": [
    "data = client.completions.create(\n",
    "  model=\"gpt-3.5-turbo-instruct\",\n",
    "  prompt=\"讲10个给程序员听得笑话\",\n",
    "  max_tokens=1000,\n",
    "  temperature=0.5\n",
    ")"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "f04959ba-5781-4e9e-bdfb-a55f0698acd9",
   "metadata": {},
   "source": [
    "text = data.choices[0].text\n",
    "print(text)"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "ad54c353-64bf-44dc-ad55-1d2c4a783443",
   "metadata": {},
   "source": [],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "id": "3e5bdaff-764f-4fbf-b2c2-a8afbdaca8c6",
   "metadata": {},
   "source": [
    "## 生成 Python 代码，并执行和验证\n",
    "\n",
    "以面试中考察的典型的试题 `快速排序` 为例"
   ]
  },
  {
   "cell_type": "code",
   "id": "3d5a6a51-57cd-4890-8978-b07efa2c28e2",
   "metadata": {},
   "source": [
    "data = client.completions.create(\n",
    "  model=\"gpt-3.5-turbo-instruct\",\n",
    "  prompt=\"生成可执行的快速排序 Python 代码\",\n",
    "  max_tokens=1000,\n",
    "  temperature=0\n",
    ")\n"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "45e24e7d-72d7-491a-a60f-0e8031a6fc7d",
   "metadata": {},
   "source": [
    "text = data.choices[0].text\n",
    "print(text)"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "id": "49c6675c-611e-4933-9fca-804200eef339",
   "metadata": {},
   "source": [
    "#### Prompt：Jupyter Notebook 中执行生成的代码\n",
    "\n",
    "Prompt：\n",
    "\n",
    "```\n",
    "我现在用 Completion API 生成了 Python 代码，并以字符串形式存放在 text 中，如下所示：\n",
    "\n",
    "text = data.choices[0].text\n",
    "print(text)\n",
    "\n",
    "def quick_sort(arr):\n",
    "    if len(arr) <= 1:\n",
    "        return arr\n",
    "    pivot = arr[0]\n",
    "    left = [x for x in arr[1:] if x <= pivot]\n",
    "    right = [x for x in arr[1:] if x > pivot]\n",
    "    return quick_sort(left) + [pivot] + quick_sort(right)\n",
    "\n",
    "如何在 Jupyter notebook 中执行text中存放的这段代码\n",
    "```\n"
   ]
  },
  {
   "cell_type": "code",
   "id": "21707523-bde6-48b9-ac9d-da693045f7c5",
   "metadata": {},
   "source": [
    "# `exec` 函数会执行传入的字符串作为 Python 代码。\n",
    "# 在这个例子中，我们使用 `exec` 来定义了一个 `quick_sort` 函数，然后你就可以调用这个函数了。\n",
    "# 请注意，`exec` 可以执行任何 Python 代码，因此在使用它的时候一定要小心，特别是当你执行的代码来自不可信的来源时。\n",
    "exec(text)"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "15918392-560b-4826-8800-4c7a11167579",
   "metadata": {},
   "source": [
    "# 现在你可以调用这个函数了\n",
    "print(quick_sort([12,3,6,8,10,1,2,1]))"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "id": "cd669a78-125f-478f-b3d9-677f137d9398",
   "metadata": {},
   "source": [
    "# 聊天机器人初探（Chat Completions API）\n",
    "\n",
    "使用 Chat Completions API 实现对话任务\n",
    "\n",
    "聊天补全(Chat Completions API)以消息列表作为输入，并返回模型生成的消息作为输出。尽管聊天格式旨在使多轮对话变得简单，但它同样适用于没有任何对话的单轮任务。\n",
    "\n",
    "主要请求参数说明：\n",
    "\n",
    "\n",
    "- **`model` （string，必填）**\n",
    "\n",
    "  要使用的模型ID。有关哪些模型适用于Chat API的详细信息\n",
    "\n",
    "- **`messages` （array，必填）**\n",
    "\n",
    "  迄今为止描述对话的消息列表\n",
    "    - **`role` （string，必填）**\n",
    "\n",
    "  发送此消息的角色。`system` 、`user` 或 `assistant` 之一（一般用 user 发送用户问题，system 发送给模型提示信息）\n",
    "\n",
    "    - **`content` （string，必填）**\n",
    "    \n",
    "      消息的内容\n",
    "    \n",
    "    - **`name` （string，选填）**\n",
    "    \n",
    "      此消息的发送者姓名。可以包含 a-z、A-Z、0-9 和下划线，最大长度为 64 个字符\n",
    "\n",
    "- **`stream` （boolean，选填，是否按流的方式发送内容）**\n",
    "\n",
    "  当它设置为 true 时，API 会以 SSE（ Server Side Event ）方式返回内容。SSE 本质上是一个长链接，会持续不断地输出内容直到完成响应。如果不是做实时聊天，默认false即可。\n",
    "\n",
    "- **`max_tokens` （integer，选填）**\n",
    "\n",
    "  在聊天补全中生成的最大 **tokens** 数。\n",
    "\n",
    "  输入token和生成的token的总长度受模型上下文长度的限制。\n",
    "\n",
    "- **`temperature` （number，选填，默认是 1）**\n",
    "\n",
    "  采样温度，在 0和 2 之间。\n",
    "\n",
    "  较高的值，如0.8会使输出更随机，而较低的值，如0.2会使其更加集中和确定性。\n",
    "\n",
    "  通常建议修改这个（`temperature` ）或者 `top_p` ，但两者不能同时存在，二选一。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d00108e4-b98e-4d55-a1e2-78845b321fec",
   "metadata": {},
   "source": [
    "## 开启聊天模式\n",
    "\n",
    "使用 `messages` 记录迄今为止对话的消息列表"
   ]
  },
  {
   "cell_type": "code",
   "id": "172f2eb6-2d2b-4d10-9887-5e4af011c77f",
   "metadata": {},
   "source": [
    "from openai import OpenAI\n",
    "client = OpenAI(base_url='https://bd-gateway-agent.sdpsg.101.com/openai/v1/', api_key=os.getenv('OPENAI_API_KEY'))    # 使用网龙自己的URL\n",
    "\n",
    "messages=[\n",
    "    {\n",
    "        \"role\": \"user\", \n",
    "        \"content\": \"Hello!\"\n",
    "    }\n",
    "]\n",
    "\n",
    "\n",
    "data = client.chat.completions.create(\n",
    "  model=\"gpt-3.5-turbo\",\n",
    "  messages = messages\n",
    ")\n"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "158a8a3b-0a73-4157-9025-8282527fd692",
   "metadata": {},
   "source": [
    "print(data)"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "d872f47e-b768-4d3e-850f-c2034e2e2263",
   "metadata": {},
   "source": [
    "# 从返回的数据中获取生成的消息\n",
    "new_message = data.choices[0].message\n",
    "# 打印 new_message\n",
    "print(new_message)"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "ee8c6048-2fed-4a81-90cc-45f526630aad",
   "metadata": {},
   "source": [
    "# 将消息追加到 messages 列表中\n",
    "messages.append(new_message)\n",
    "print(messages)"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "1f88a3a6-c6ad-47a2-a187-40f4e921b54f",
   "metadata": {},
   "source": [
    "type(new_message)"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "4dc4a02b-2c19-4114-bfad-7b8364d1f8fd",
   "metadata": {},
   "source": [
    "new_message.role"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "843e1454-85b9-409f-8a6a-c84fadcab05a",
   "metadata": {},
   "source": [
    "new_message.content"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "626586e5-55c0-4b1c-8dc4-175edab9b7c4",
   "metadata": {},
   "source": [
    "messages.pop()"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "bbf5b445-f0b2-422c-befd-2738982903d4",
   "metadata": {},
   "source": [
    "print(messages)"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "id": "5a9d6f7b-09fd-4bed-bcde-2ab50d3d415c",
   "metadata": {},
   "source": [
    "#### Prompt: OpenAIObject -> Dict\n",
    "\n",
    "```\n",
    "打印 messages 列表后发现数据类型不对，messages 输出如下：\n",
    "\n",
    "print(messages)\n",
    "\n",
    "[{'role': 'user', 'content': 'Hello!'}, <OpenAIObject at 0x7f27582c13f0> JSON: {\n",
    "  \"content\": \"Hello! How can I assist you today?\",\n",
    "  \"role\": \"assistant\"\n",
    "}]\n",
    "\n",
    "将OpenAIObject 转换为一个如下数据类型格式：\n",
    "\n",
    "    {\n",
    "        \"role\": \"user\", \n",
    "        \"content\": \"Hello!\"\n",
    "    }\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "id": "8d9052f8-88ef-4b71-8fa8-42bff7304537",
   "metadata": {},
   "source": [
    "new_message = data.choices[0].message\n",
    "new_message_dict = {\"role\": new_message.role, \"content\": new_message.content}\n",
    "type(new_message_dict)"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "699416f3-ee26-432a-8ad5-27b151f24846",
   "metadata": {},
   "source": [
    "print(new_message_dict)"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "7a11a2c6-3f2b-4c35-b987-f396f839da7c",
   "metadata": {},
   "source": [
    "# 将消息追加到 messages 列表中\n",
    "messages.append(new_message_dict)"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "id": "532671cb-6ceb-472f-98c8-c86a38c08bc6",
   "metadata": {},
   "source": [
    "print(messages)"
   ],
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "id": "f7a5d741-5b2e-4f1a-8a74-e3b559874079",
   "metadata": {},
   "source": [
    "#### 新一轮对话"
   ]
  },
  {
   "cell_type": "code",
   "id": "ad2e089b-ba80-477b-92d1-c183f11082c8",
   "metadata": {},
   "source": [
    "new_chat = {\n",
    "    \"role\": \"user\",\n",
    "    \"content\": \"1.讲一个程序员才听得懂的冷笑话；2.今天是几号？3.明天星期几？\"\n",
    "}"
   ],
   "outputs": [],
   "execution_count": 5
  },
  {
   "cell_type": "code",
   "id": "780f361d-b9e1-4343-8851-089d4c0aecde",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-13T03:20:11.428890Z",
     "start_time": "2024-05-13T03:20:11.398972Z"
    }
   },
   "source": [
    "messages.append(new_chat)"
   ],
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'messages' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mNameError\u001B[0m                                 Traceback (most recent call last)",
      "Cell \u001B[1;32mIn[6], line 1\u001B[0m\n\u001B[1;32m----> 1\u001B[0m \u001B[43mmessages\u001B[49m\u001B[38;5;241m.\u001B[39mappend(new_chat)\n",
      "\u001B[1;31mNameError\u001B[0m: name 'messages' is not defined"
     ]
    }
   ],
   "execution_count": 6
  },
  {
   "cell_type": "code",
   "id": "32b195bb-52ca-4b7f-a1f6-5b183ffbd58f",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-13T03:20:11.648304Z",
     "start_time": "2024-05-13T03:20:11.631349Z"
    }
   },
   "source": [
    "from pprint import pprint\n",
    "\n",
    "pprint(messages)"
   ],
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'messages' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mNameError\u001B[0m                                 Traceback (most recent call last)",
      "Cell \u001B[1;32mIn[7], line 3\u001B[0m\n\u001B[0;32m      1\u001B[0m \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01mpprint\u001B[39;00m \u001B[38;5;28;01mimport\u001B[39;00m pprint\n\u001B[1;32m----> 3\u001B[0m pprint(\u001B[43mmessages\u001B[49m)\n",
      "\u001B[1;31mNameError\u001B[0m: name 'messages' is not defined"
     ]
    }
   ],
   "execution_count": 7
  },
  {
   "cell_type": "code",
   "id": "54b0532a-0099-40e3-8a3d-9dc72d6eccbd",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-13T03:20:11.678584Z",
     "start_time": "2024-05-13T03:20:11.660633Z"
    }
   },
   "source": [
    "data = client.chat.completions.create(\n",
    "  model=\"gpt-3.5-turbo\",\n",
    "  messages=messages\n",
    ")"
   ],
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'messages' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mNameError\u001B[0m                                 Traceback (most recent call last)",
      "Cell \u001B[1;32mIn[8], line 3\u001B[0m\n\u001B[0;32m      1\u001B[0m data \u001B[38;5;241m=\u001B[39m client\u001B[38;5;241m.\u001B[39mchat\u001B[38;5;241m.\u001B[39mcompletions\u001B[38;5;241m.\u001B[39mcreate(\n\u001B[0;32m      2\u001B[0m   model\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mgpt-3.5-turbo\u001B[39m\u001B[38;5;124m\"\u001B[39m,\n\u001B[1;32m----> 3\u001B[0m   messages\u001B[38;5;241m=\u001B[39m\u001B[43mmessages\u001B[49m\n\u001B[0;32m      4\u001B[0m )\n",
      "\u001B[1;31mNameError\u001B[0m: name 'messages' is not defined"
     ]
    }
   ],
   "execution_count": 8
  },
  {
   "cell_type": "code",
   "id": "edad9b8d-2b46-4cd4-ba03-51c96cc4c175",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-13T03:20:11.739421Z",
     "start_time": "2024-05-13T03:20:11.714488Z"
    }
   },
   "source": [
    "new_message = data.choices[0].message\n",
    "# 打印 new_messages \n",
    "print(new_message)"
   ],
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'data' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mNameError\u001B[0m                                 Traceback (most recent call last)",
      "Cell \u001B[1;32mIn[9], line 1\u001B[0m\n\u001B[1;32m----> 1\u001B[0m new_message \u001B[38;5;241m=\u001B[39m \u001B[43mdata\u001B[49m\u001B[38;5;241m.\u001B[39mchoices[\u001B[38;5;241m0\u001B[39m]\u001B[38;5;241m.\u001B[39mmessage\n\u001B[0;32m      2\u001B[0m \u001B[38;5;66;03m# 打印 new_messages \u001B[39;00m\n\u001B[0;32m      3\u001B[0m \u001B[38;5;28mprint\u001B[39m(new_message)\n",
      "\u001B[1;31mNameError\u001B[0m: name 'data' is not defined"
     ]
    }
   ],
   "execution_count": 9
  },
  {
   "cell_type": "code",
   "id": "bedc91c2-4216-4686-b66c-df012a9778c8",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-13T03:20:11.770339Z",
     "start_time": "2024-05-13T03:20:11.745406Z"
    }
   },
   "source": [
    "# 打印 new_messages 内容\n",
    "print(new_message.content)"
   ],
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'new_message' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mNameError\u001B[0m                                 Traceback (most recent call last)",
      "Cell \u001B[1;32mIn[10], line 2\u001B[0m\n\u001B[0;32m      1\u001B[0m \u001B[38;5;66;03m# 打印 new_messages 内容\u001B[39;00m\n\u001B[1;32m----> 2\u001B[0m \u001B[38;5;28mprint\u001B[39m(\u001B[43mnew_message\u001B[49m\u001B[38;5;241m.\u001B[39mcontent)\n",
      "\u001B[1;31mNameError\u001B[0m: name 'new_message' is not defined"
     ]
    }
   ],
   "execution_count": 10
  },
  {
   "cell_type": "markdown",
   "id": "877f2ff6-8bac-43a9-a827-e472c5698ed4",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "code",
   "id": "903ec93e-fba9-403e-bfe4-b749f91abb0c",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-13T03:20:11.802254Z",
     "start_time": "2024-05-13T03:20:11.796270Z"
    }
   },
   "source": [],
   "outputs": [],
   "execution_count": 10
  },
  {
   "cell_type": "markdown",
   "id": "7f417580-7810-4f0e-ad5c-6d2e0f9e7f42",
   "metadata": {},
   "source": [
    "## 使用多种身份聊天对话\n",
    "\n",
    "目前`role`参数支持3类身份： `system`, `user` `assistant`:\n",
    "\n",
    "\n",
    "![](images/chat_completion_api.png)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "id": "0981fe4b-410d-4d70-b07c-78a88e46b7af",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-13T03:20:18.782128Z",
     "start_time": "2024-05-13T03:20:18.769179Z"
    }
   },
   "source": [
    "# 构造聊天记录\n",
    "messages=[\n",
    "    {\"role\": \"system\", \"content\": \"你是一个Unreal方面的开发专家。\"},\n",
    "    {\"role\": \"user\", \"content\": \"在Unreal5.3中，如何获取Sequencer上绑定的Spawnable或Possessable对象？\"},\n",
    "]"
   ],
   "outputs": [],
   "execution_count": 11
  },
  {
   "cell_type": "code",
   "id": "7d135caf-b778-4d50-b738-a429398c6eaa",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-13T03:20:28.469261Z",
     "start_time": "2024-05-13T03:20:21.179777Z"
    }
   },
   "source": [
    "import openai\n",
    "\n",
    "data = client.chat.completions.create(\n",
    "  model=\"gpt-3.5-turbo\",\n",
    "  messages=messages\n",
    ")\n"
   ],
   "outputs": [],
   "execution_count": 12
  },
  {
   "cell_type": "code",
   "id": "e97b0145-af2f-47bb-865f-9b2a8f4e6353",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-13T03:20:32.098527Z",
     "start_time": "2024-05-13T03:20:32.092544Z"
    }
   },
   "source": [
    "message = data.choices[0].message.content\n",
    "print(message)"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "在Unreal Engine 5.3中，要获取Sequencer上绑定的Spawnable或Possessable对象，可以通过以下步骤实现：\n",
      "\n",
      "1. 首先，在你的代码中引入Sequencer模块：\n",
      "```cpp\n",
      "#include \"MovieSceneSequence.h\"\n",
      "#include \"MovieSceneSequencePlayer.h\"\n",
      "#include \"MovieSceneSpawnable.h\"\n",
      "#include \"MovieScenePossessable.h\"\n",
      "```\n",
      "\n",
      "2. 然后，获取当前正在播放的Sequencer序列的播放器对象：\n",
      "```cpp\n",
      "UMovieSceneSequence* CurrentSequence = // 获取当前正在播放的Sequencer序列\n",
      "UMovieSceneSequencePlayer* SequencePlayer = // 获取当前正在播放的Sequencer序列的播放器对象\n",
      "```\n",
      "\n",
      "3. 接下来，通过播放器对象获取Spawnable或Possessable对象：\n",
      "```cpp\n",
      "for (const FMovieScenePossessable& Possessable : CurrentSequence->GetMovieScene()->Possessables)\n",
      "{\n",
      "    // 获取Possessable对象的信息\n",
      "}\n",
      "\n",
      "for (const FMovieSceneSpawnable& Spawnable : CurrentSequence->GetMovieScene()->Spawnables)\n",
      "{\n",
      "    // 获取Spawnable对象的信息\n",
      "}\n",
      "```\n",
      "\n",
      "通过上述步骤，你可以在Unreal Engine 5.3中获取Sequencer上绑定的Spawnable或Possessable对象的信息。\n"
     ]
    }
   ],
   "execution_count": 13
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "fd56c185-b6e0-4ade-8236-9e2549182ab2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 添加 GPT 返回结果到聊天记录\n",
    "messages.append({\"role\": \"assistant\", \"content\": message})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "a860210e-be0d-468e-8845-8ffceaecb034",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[{'role': 'system', 'content': '你是一个乐于助人的体育界专家。'},\n",
       " {'role': 'user', 'content': '2008年奥运会是在哪里举行的？'},\n",
       " {'role': 'assistant', 'content': '2008年夏季奥运会在中国北京举行。'}]"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "messages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "99bae857-2854-4090-8a4d-8e1930f70464",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 第二轮对话\n",
    "messages.append({\"role\": \"user\", \"content\": \"1.金牌最多的是哪个国家？2.奖牌最多的是哪个国家？\"})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "f07bbb71-fe19-4582-b1f3-3ee994fcec0b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[{'role': 'system', 'content': '你是一个乐于助人的体育界专家。'},\n",
       " {'role': 'user', 'content': '2008年奥运会是在哪里举行的？'},\n",
       " {'role': 'assistant', 'content': '2008年夏季奥运会在中国北京举行。'},\n",
       " {'role': 'user', 'content': '1.金牌最多的是哪个国家？2.奖牌最多的是哪个国家？'}]"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "messages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "a138da7f-b5b3-40a1-b30b-4e6b0c8e249f",
   "metadata": {},
   "outputs": [],
   "source": [
    "data = client.chat.completions.create(\n",
    "  model=\"gpt-3.5-turbo\",\n",
    "  messages=messages\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "f531bc4d-3eeb-49f7-b717-0986f2b4af2c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1. 2008年夏季奥运会中，金牌最多的国家是中国，共获得51枚金牌。\n",
      "2. 2008年夏季奥运会中，奖牌最多的国家是中国，共获得100枚奖牌（51枚金牌、21枚银牌、28枚铜牌）。\n"
     ]
    }
   ],
   "source": [
    "message = data.choices[0].message.content\n",
    "print(message)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "3500811e-3a80-4ed0-9770-a1f761dfab6b",
   "metadata": {},
   "outputs": [],
   "source": [
    "data = client.chat.completions.create(\n",
    "  model=\"gpt-3.5-turbo\",\n",
    "  messages=[{'role': 'user', 'content': '1.金牌最多的是哪个国家？2.奖牌最多的是哪个国家？'}]\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "cd59b92d-8362-4215-8865-82fe5cafce56",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'1. 根据2021年东京奥运会的数据，金牌最多的国家是美国。\\n\\n2. 根据2021年东京奥运会的数据，奖牌最多的国家是美国。'"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.choices[0].message.content"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "25220ddb-b894-41b0-a36f-aadfc18d1b23",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
